require 'ethereum'
require 'gen_eth_contract'


namespace :contracts do
  desc "Compile a contract"
  task :compile, [:path] do |_, args|
    paths = []
    paths << "#{Dir.pwd}/contracts/SafeMath.sol"
    paths << "#{Dir.pwd}/contracts/Owned.sol"
    #paths << "#{Dir.pwd}/contracts/ERC20Token.sol"
    #paths << "#{Dir.pwd}/contracts/StandardToken.sol"
    #paths << "#{Dir.pwd}/contracts/ATMToken.sol"
    paths << "#{Dir.pwd}/contracts/Contribution.sol"
    paths.each do |path|
      contract_name = File.basename(path).gsub('.sol', '')
      contract = Ethereum::Solidity.new.compile(path)
      puts "Contract abi:"
      puts contract.map { |k, v| "#{k}: #{v["abi"]}" }.join("\n\n")
      abi = File.open("#{Dir.pwd}/contracts/build/#{contract_name}.abi", "w")
      abi.write contract.map { |k, v| "#{k}: #{v["abi"]}" }.join("\n\n")
      abi.close
      #puts
      #puts "Contract binary code:"
      contract.map { |k, v| "#{k}: #{v["bin"]}" }.join("\n\n")
      bin = File.open("#{Dir.pwd}/contracts/build/#{contract_name}.bin", "w")
      bin.write contract.map { |k, v| "#{k}: #{v["bin"]}" }.join("\n\n")
      bin.close
    end
  end

  desc "deploy contract"
  task :deploy, [:path] do |_, args|
    desc "Deploing contract #{args[:path]}"
    contracts = []
    contracts << {'path' => "#{Dir.pwd}/contracts/SafeMath.sol", 'params' => []}
    contracts << {'path' => "#{Dir.pwd}/contracts/Owned.sol", 'params' => []}
    #contracts << {'path' => "#{Dir.pwd}/contracts/ERC20Token.sol", 'params' => []}
    #contracts << {'path' => "#{Dir.pwd}/contracts/StandardToken.sol", 'params' => []}
    #contracts << {'path' => "#{Dir.pwd}/contracts/ATMToken.sol", 'params' => [100]}
    contracts << {'path' => "#{Dir.pwd}/contracts/Contribution.sol", 'params' => ['0x6704fbfcd5ef766b287262fa2281c105d57246a6', '0x9e1ef1ec212f5dffb41d35d9e5c14054f26c6560', Time.now.to_i + 10, 60]}

    contracts.each do |contract|
      path = contract['path']
      params = contract['params']
      contract_name = File.basename(path).gsub('.sol', '')
      works = Ethereum::Contract.create(file: path)
      if params.empty?
        works.deploy_and_wait { puts "." }
      else
        works.deploy_and_wait(*params) { puts "." }
      end
      address = works.deployment.contract_address
      ipfile = File.open("#{Dir.pwd}/contracts/build/#{contract_name}.ip", "w")
      ipfile.write address
      ipfile.close
      puts "Contract: #{contract_name} deployed under address: #{address}"
    end
  end

  desc "deploy contract and generate class"
  task :gen_deploy, [:path] do |_, args|
    desc "Deploing contract #{args[:path]}"
    contracts = []
    contracts << {'path' => "#{Dir.pwd}/contracts/SafeMath.sol", 'params' => []}
    contracts << {'path' => "#{Dir.pwd}/contracts/Owned.sol", 'params' => []}
    #contracts << {'path' => "#{Dir.pwd}/contracts/ERC20Token.sol", 'params' => []}
    #contracts << {'path' => "#{Dir.pwd}/contracts/StandardToken.sol", 'params' => []}
    #contracts << {'path' => "#{Dir.pwd}/contracts/ATMToken.sol", 'params' => [100]}
    contracts << {'path' => "#{Dir.pwd}/contracts/Contribution.sol", 'params' => ['0x6704fbfcd5ef766b287262fa2281c105d57246a6', '0x9e1ef1ec212f5dffb41d35d9e5c14054f26c6560', Time.now.to_i + 20, 60]}

    contracts.each do |contract|
      path = contract['path']
      params = contract['params']
      contract_name = File.basename(path).gsub('.sol', '')

      contracts_abi = Ethereum::Solidity.new.compile(path)
      #主合约的ABI
      main_abi = contracts_abi[contract_name]['abi']
      puts main_abi
      works = Ethereum::Contract.create(file: path)
      if params.empty?
        works.deploy_and_wait { puts "." }
      else
        works.deploy_and_wait(*params) { puts "." }
      end
      address = works.deployment.contract_address
      ipfile = File.open("#{Dir.pwd}/contracts/build/#{contract_name}.ip", "w")
      ipfile.write address
      ipfile.close
      puts "Contract: #{contract_name} deployed under address: #{address}"

      #生成Contract Class
      GenEthContract.gen_contract(contract_name, address, main_abi)
      puts "Contract: #{contract_name} Class generate succ"

      #生成Contract Scaffold
      GenEthContract.gen_contract_controller(contract_name, address, main_abi)
      GenEthContract.gen_contract_view(contract_name, address, main_abi)
      GenEthContract.add_route(contract_name, address, main_abi)
      puts "Contract: #{contract_name} Class Scaffold generate succ"

    end
  end



end
